package com.abing.starry.manager;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.abing.starry.common.ErrorCode;
import com.abing.starry.config.CaptchaProperties;
import com.abing.starry.exception.BusinessException;
import com.abing.starry.util.CaptchaUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import java.io.File;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.abing.starry.constant.UserConstant.USER_MAIL_CAPTCHA;
import static com.abing.starry.constant.UserConstant.USER_MAIL_CAPTCHA_EXPIRE;

/**
 * @Author CaptainBing
 * @Date 2024/8/21 15:34
 * @Description
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MailManager {

    private final JavaMailSender javaMailSender;

    private final StringRedisTemplate stringRedisTemplate;

    private final Configuration freeMarkerConfiguration;

    private final CaptchaProperties captchaProperties;


    @Value("${spring.mail.from}")
    private String from;

    /**
     * 发送简单邮件
     * @param to 发给谁
     * @param subject 主题
     * @param content 邮件内容
     */
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        javaMailSender.send(message);

    }

    /**
     * 发送邮件
     * @param to 邮箱账号
     */
    public void sendCaptchaToSomebodyForLogin(String to){

        // 邮箱验证码十分钟内有效
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        String userMailCaptchaKey = USER_MAIL_CAPTCHA + to;
        String userMailCaptcha = stringRedisTemplate.opsForValue().get(userMailCaptchaKey);
        if (StringUtils.isEmpty(userMailCaptcha)){
            userMailCaptcha = CaptchaUtils.random6Captcha();
            stringRedisTemplate.opsForValue().set(userMailCaptchaKey, userMailCaptcha, captchaProperties.getTtl(), TimeUnit.MINUTES);
            String userMailCaptchaExpireKey = USER_MAIL_CAPTCHA_EXPIRE + to;
            stringRedisTemplate.opsForValue().set(userMailCaptchaExpireKey,"",captchaProperties.getRepeatSubmit(),TimeUnit.MINUTES);
        }
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
        try {
            mimeMessageHelper.setFrom(from);
            mimeMessageHelper.setTo(to);
            mimeMessageHelper.setSubject("平台登录验证码");
            String emailTemplate = createEmailTemplate(to,userMailCaptcha);
            mimeMessageHelper.setText(emailTemplate,true);
        } catch (MessagingException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "发送邮件失败:" + to);
        }
        javaMailSender.send(mimeMessage);
        stopWatch.stop();
        log.info("邮件发送成功,事件:发送验证码,用户:{},耗时:{} ms",to,stopWatch.getTotalTimeMillis());
    }

    /**
     * 创建邮件发送模板
     * @param to 发给谁
     * @param captcha 验证码
     * @return
     */
    private String createEmailTemplate(String to, String captcha){
        String emailTemplatePath = "";
        try {

            Template template = freeMarkerConfiguration.getTemplate("EmailTemplate.html.ftl");
            String workDirectory = System.getProperty("user.dir");
            String emailTemplateParentPath = workDirectory + File.separator + "emailtemplates";
            if (!FileUtil.exist(emailTemplateParentPath)) {
                FileUtil.mkdir(emailTemplateParentPath);
            }
            emailTemplatePath = emailTemplateParentPath + File.separator + RandomUtil.randomString(10) + "EmailTemplate.html";
            FileWriter writer = new FileWriter(emailTemplatePath);
            Map<String,Object> freeMarkerValueMap = new HashMap<>(2);
            List<String> verifyCodes = Arrays.stream(captcha.split("")).collect(Collectors.toList());
            freeMarkerValueMap.put("verifyCodes",verifyCodes);
            freeMarkerValueMap.put("userName",to);
            // 生成验证码邮件模板文件
            template.process(freeMarkerValueMap,writer);
            writer.close();
            return FileUtil.readString(emailTemplatePath, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "构建邮件模板失败:" + to);
        }finally {
            // 删除文件
            if (FileUtil.exist(emailTemplatePath)) {
                FileUtil.del(emailTemplatePath);
            }
        }
    }

}
